<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // 源数据
      let person = {
        name: "张三",
        age: 33,
      };

      // 模拟vue2响应式
      //#region
      /*       let p = {};
      Object.defineProperty(p, "name", {
        //  可以通过delete删除，不然不可以
        configurable: true,
        //  读取name调用
        get() {
          return person.name;
        },
        //  修改name调用
        set(value) {
          person.name = value;
        },
      });
      Object.defineProperty(p, "age", {
        //  读取age调用
        get() {
          return person.age;
        },
        //  修改age调用
        set(value) {
          person.age = value;
        },
      }); */
      //#endregion

      // vue3响应式
      // window下的Proxy代理对象
      // Reflect反射对象
      //#region
      const p = new Proxy(person, {
        //  读取p某个属性时调用
        get(target, propName) {
          console.log(`有人读取${target}身上的${propName}属性`);
          //   return target[propName];
          return Reflect.get(target, propName);
        },
        //  修改p某个属性、或给p追加某个属性时调用
        set(target, propName, value) {
          console.log(`有人修改${target}身上的${propName}属性`);
          //   target[propName] = value;
          Reflect.set(target, propName, value);
        },
        //  删除p某个属性时调用
        deleteProperty(target, propName) {
          console.log(`有人删除${target}身上的${propName}属性`);
          //   return delete target[propName];
          return Reflect.deleteProperty(target, propName);
        },
      });
      //#endregion

      let obj = {
        a: 1,
        b: 2,
      };
      // 读
      Reflect.get(obj, "a");
      // 改
      Reflect.set(obj, "a", 567);
      // 删
      Reflect.deleteProperty(obj, "a");
      /* 
            Object.defineProperty不能重定义，后续代码不能执行
                封装框架：不好捕获错误，使用try{}catch(error){}
            Reflect.defineProperty，返回true/false，重定义后续代码可以执行
                框架封装更友好
      */
    </script>
  </body>
</html>
